/////////////////////////////////////////////////////////////////////////////
// Name:        SCDisplayFrame.hpp
// Purpose:     
// Author:      Erwan Le Martelot
// Modified by: 
// Created:     18/04/2007 12:58:36
// RCS-ID:      
// Copyright:   
// Licence:     
/////////////////////////////////////////////////////////////////////////////

#ifndef _SCDISPLAYFRAME_H_
#define _SCDISPLAYFRAME_H_

#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma interface "SCDisplayFrame.hpp"
#endif

/*!
 * Includes
 */

////@begin includes
#include "wx/glcanvas.h"
////@end includes

// ----- My Includes ----- //
#include "SCSystem.hpp"
#include "SCEngine.hpp"
#include <vector>
#include <map>
#include <algorithm>
#include "Point3D.hpp"
#include "Triple.hpp"
#include "Graph.hpp"
// ----------------------- //

#define Type(S) (S).GetKernel().substr(4,4)
#define Axon 			"1110"
#define Synapse			"0101"
#define InputTransfer	"0110"
#define OutputTransfer	"0111"
#define Soma			"0011"
#define Dendrites		"1111"
#define SynapticConnection "1000"

/*
// ---- My Structures ---- //
// RGB Colour structure
typedef struct colour {
	float r, g, b;
};
// ----------------------- //

struct Constraint {

	/// Compare two constraints
	const bool operator == (const Constraint & c) {
		return	(	((this->sys1 == c.sys1) && (this->sys2 == c.sys2)) ||
					((this->sys1 == c.sys2) && (this->sys2 == c.sys1))	) &&
				(this->dist == c.dist) &&
				(this->req_dist == c.req_dist);
	}

	/// First system involved
	SC::SCSystem const * sys1;
	
	/// Second system involved
	SC::SCSystem const * sys2;
	
	/// Distance between the two systems
	float dist;
	
	/// Required distance to reach at least to solve the constraint
	float req_dist;

};
*/

/*!
 * Forward declarations
 */

////@begin forward declarations
class SCDisplayFrame;
////@end forward declarations

/*!
 * Control identifiers
 */

////@begin control identifiers
#define ID_GLCANVAS 10017
////@end control identifiers

/*!
 * Compatibility
 */

#ifndef wxCLOSE_BOX
#define wxCLOSE_BOX 0x1000
#endif

/*!
 * SCDisplayFrame class declaration
 */

class SCDisplayFrame: public wxGLCanvas
{    
	DECLARE_CLASS( SCDisplayFrame )
	DECLARE_EVENT_TABLE()

public:
	/// Constructors
	SCDisplayFrame( wxWindow* parent, wxWindowID id = ID_GLCANVAS, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxSTATIC_BORDER, const wxString& name = wxT("GLCanvas"), int* attribs = NULL );

	/// Creation
	bool Create( wxWindow* parent, wxWindowID id = ID_GLCANVAS, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxSTATIC_BORDER, const wxString& name = wxT("GLCanvas"), int* attribs = NULL );

	/// Initialises member variables
	void Init();

	/// Creates the controls and sizers
	void CreateControls();

////@begin SCDisplayFrame event handler declarations

	/// wxEVT_SIZE event handler for ID_GLCANVAS
	void OnSize( wxSizeEvent& event );

	/// wxEVT_PAINT event handler for ID_GLCANVAS
	void OnPaint( wxPaintEvent& event );

////@end SCDisplayFrame event handler declarations

////@begin SCDisplayFrame member function declarations

	//std::vector<colour> GetColours() const { return colours ; }
	//void SetColours(std::vector<colour> value) { colours = value ; }

	//bool GetDisplayOrtho() const { return display_ortho ; }
	//void SetDisplayOrtho(bool value) { display_ortho = value ; }

	SC::SCEngine * GetEngine() const { return engine ; }
	void SetEngine(SC::SCEngine * value) { engine = value ; }

	/// Retrieves bitmap resources
	wxBitmap GetBitmapResource( const wxString& name );

	/// Retrieves icon resources
	wxIcon GetIconResource( const wxString& name );
////@end SCDisplayFrame member function declarations

	/// Should we show tooltips?
	static bool ShowToolTips();

////@begin SCDisplayFrame member variables
protected:
	//std::vector<colour> colours;
	//bool display_ortho;
	SC::SCEngine * engine;
	std::map<const SC::SCSystem *,float> sys_sizes;
	//std::map<const SC::SCSystem *,Types::Point3D<float> > sys_locations;
	//std::vector<unsigned int> types;
	//std::vector<const SC::SCSystem *> last_involved;
////@end SCDisplayFrame member variables
public:
	/// Returns the ith colour (read-only)
	//const colour & GetColourAt(const unsigned int i) { return this->colours[i]; }
	/// Returns the ith colour
	//colour & ColourAt(const unsigned int i) { return this->colours[i]; }
	/// Reload data for display
	//void ReloadData(const std::vector<unsigned int> &);
	// (Re)Place systems
	//void PlaceSystems();
	// Set last involved systems
	//void SetLastInvolved(const std::vector<const SC::SCSystem *> & value) { this->last_involved = value ; }
	void ReloadData();
protected:
	Types::Graph< Types::Triple<std::string,const SC::SCSystem*,Types::Point3D<float> > > net_graph;
	void InitGL();
	void buildGraphStructure(const std::vector<SC::SCSystem> &);
	void computeNodesLocation();
	const int findNodeIndexFromSystem(const SC::SCSystem &);
	void setGraphArcs(const std::vector<SC::SCSystem> &);
	void drawGraph();
	//const float setSizes(const SC::SCSystem &, std::vector<const SC::SCSystem *> &);
	//const bool satisfyConstraints();
	//const bool pickupConstraint(Constraint & constraint);
	//std::vector<Constraint> getSystemUpwardConstraints(const SC::SCSystem &);
};

#endif
	// _SCDISPLAYFRAME_H_
